from machine import Timer
from micropython import schedule
import gc

class TimerController:
	u"""
	硬件计时器控制器类
	"""

	# 定义定时器触发时间，单位：毫秒
	TIMER_PERIOD_100 = 100
	TIMER_PERIOD_500 = 500
	TIMER_PERIOD_1000 = 1000
	TIMER_PERIOD_2000 = 2100

	# 定义是否在终端显示测距信息
	_OUTPUT_DISTANCE = False

	def __init__(self, relay, hcsr):
		u"""
		实例化计时器控制器
		"""

		# 定义 4 个定时器，分别用于：
		# 	检测 wifi 连接状态，板载 led 频闪代表等待客户端连接，熄灭代表客户端已连接
		#	获取超声波测距信息，用于自动控制继电器状态
		#	led 闪烁定时器
		#	接收客户端发送的请求

		self._prepare_active_count = 0
		self._prepare_deactive_count = 0
		self._wifi_status_timer = Timer(0)
		self._distance_info_timer = Timer(1)
		self._led_blink_timer = Timer(2)
		self._client_request_timer = Timer(3)

		self._distance_status = False
		self._relay = relay
		self._hcsr = hcsr

	def start_wifi_status_timer(self, check_wifi_status_cb):
		self._wifi_status_timer.init(
			mode = Timer.PERIODIC,
			period = self.TIMER_PERIOD_2000,  # 每2秒执行一次，如果没有客户端连接热点，板载 led 每2秒闪烁一次
			callback = lambda timer: schedule(check_wifi_status_cb, timer)
		)
		gc.collect()

	def start_led_blink_timer(self, led):
		self._led_blink_timer.init(
			mode = Timer.PERIODIC,
			period = self.TIMER_PERIOD_1000,
			callback = lambda timer: led.value(not led.value())
		)
		gc.collect()

	def stop_led_blink_timer(self):
		self._led_blink_timer.deinit()

	def start_client_request_timer(self, check_client_request_cb):
		self._client_request_timer.init(
			mode = Timer.PERIODIC,
			period = self.TIMER_PERIOD_500,
			callback = lambda timer: schedule(check_client_request_cb, timer)
		)
		gc.collect()

	def start_distance_info_timer(self):
		self._distance_info_timer.init(
			mode = Timer.PERIODIC, # 启动模式为 周期性执行
			# mode = Timer.ONE_SHOT, 启动模式为 只执行一次，必须二选一
			period = self.TIMER_PERIOD_100, # 执行周期为每100毫秒执行一次
			callback = lambda timer: schedule(self._get_distance_info_cb, timer)
		)
		gc.collect()

		self._distance_status = True

	def stop_distance_info_timer(self):
		#self._relay.deactive()
		self._distance_info_timer.deinit()

		self._distance_status = False
		self._prepare_active_count = 0
		self._prepare_deactive_count = 0

	def _get_distance_info_cb(self, timer):
		m, dm, cm, mm = self._hcsr.getDistance()

		if (m == -1):
			print("timeout while opening echo port")
		elif (m == -2):
			print("timeout while closing echo port")
		else:
			if (self._OUTPUT_DISTANCE):
				print("distance: %s cm" % cm)

			if (cm < 30):
				self._prepare_active_count += 1

				if (self._prepare_active_count >= 20):
					if (not self.get_relay_status):
						self.active_relay()

					self._prepare_active_count = 0
					self._prepare_deactive_count = 0
			else:
				self._prepare_deactive_count += 1

				if (self._prepare_deactive_count >= 30):
					self.deactive_relay()

					self._prepare_deactive_count = 0

	def active_relay(self):
		self._relay.active(self._relay.ACTIVE_TIME_INFINITE)

	def deactive_relay(self):
		self._relay.deactive()

	@property
	def get_distance_status(self):
		u"""
		获取 继电器模块 是否由 超声波测距模块 自动控制
		:return: 1代表 继电器模块 由 超声波测距模块 自动控制，0代表手动控制
		"""
		#return "1" if (self._distance_status) else "0"
		return self._distance_status

	@property
	def get_relay_status(self):
		u"""
		获取 继电器模块 工作状态，是否激活
		:return: 1代表 继电器模块 已激活，0代表未激活
		"""

		return self._relay.isActived
		#return "1" if (relay.isActived) else "0"
